package nr.nodehost;

//todo implement

import com.sun.management.OperatingSystemMXBean;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.*;
import java.nio.ByteBuffer;

import static java.lang.Thread.sleep;


@EnableAsync
@Component
public class ResourceGetter {
    @Value("${node.ip}")
    private String nodeIp;
    @Value("${node.Resource.type}")
    private String resource;
    /*
     *todo 这里是udp的发送，写成循环的形式，进行发送，每次循环通过Thread.sleep(5000)来控制发送频率, 发送内容为通过
     * Linux系统调用获取的Cpu、内存、磁盘使用率等信息，通过UDP协议发送到接收端，接收端再将信息写入文件中。
     * @Async注解是Spring提供的异步执行的注解，可以用在方法上，表示该方法是异步执行的。
     */
    /**
     * 下面的是UDP发送数据的样例，可以根据需要进行修改
     */
    static void sendUDP() throws IOException {
        // 创建发送对象
        DatagramSocket ds = new DatagramSocket();
        // 打包数据
        String str = "hello UDP!";
        byte[] bytes = str.getBytes();  // udp发的数据必须是字节数组

        InetAddress address = InetAddress.getByName("255.255.255.255");
        int port = 10086;       // 接收端的端口号
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
        ds.send(dp);
        ds.close();
    }

    @Value("${simserver.nrsim_ip}")
    private String nrsim_ip;
    @Value("${simserver.nrsim_port}")
    private int nrsim_port;
    @Async
    public void test() throws IOException, InterruptedException {
        while (true)
        {
            // 创建发送对象
            DatagramSocket ds = new DatagramSocket();
            // 打包数据
            double totalmemory = getSystemTotalMemory();
            double memoryUsage = getSystemMemoryUsage();
            double cpuUsage = getSystemCpuUsage();
            String totalmemory_str = Double.toString(totalmemory);
            String memoryUsage_str = Double.toString(memoryUsage);
            String cpuUsage_str = Double.toString(cpuUsage);
            String String_all = "node_ip:" + nodeIp +
                    ", recource_type:" + resource +
                    ", totalMemory:" + totalmemory_str +
                    ", memoryUsage:" + memoryUsage_str +
                    ", cpuUsage:" + cpuUsage_str;
            JSONObject data = new JSONObject();
            data.put("node_ip", nodeIp);
            JSONObject usage = new JSONObject();
//            usage.put("TotalMemory", totalmemory_str);
            usage.put("cpuUsage", cpuUsage_str);
            usage.put("memoryUsed", memoryUsage_str);
//            usage.put("recource_type", resource);
            usage.put("gpuUsed", "");
            usage.put("fpgaUsed", "");
            usage.put("npuUsed", "");
            data.put("usage", usage);
            byte[] bytes = data.toString().getBytes();

//            String str = "hello UDP!";
//            byte[] bytes = str.getBytes();  // udp发的数据必须是字节数组

            InetAddress address = InetAddress.getByName(nrsim_ip);
            int port = nrsim_port;       // 接收端的端口号
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
            ds.send(dp);
            ds.close();
            sleep(1000);
            System.out.println("sending----------------------------");
            System.out.println(String_all);
            System.out.println(data.toString());
            System.out.println("已用物理内存: " + memoryUsage);
            System.out.println("CPU Usage: " + cpuUsage + "%");
        }
    }
    public static void main(String[] args) throws InterruptedException, IOException {
        // 在这里添加你的测试代码
        System.out.println("This is a test for YourClass");
        // 获取操作系统MXBean
        OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        // 获取总物理内存和空闲物理内存
        long totalPhysicalMemory = osBean.getTotalPhysicalMemorySize();
        long freePhysicalMemory = osBean.getFreePhysicalMemorySize();
        // 打印内存使用情况
        System.out.println("总物理内存: " + totalPhysicalMemory / (1024 * 1024) + " MB");
        System.out.println("空闲物理内存: " + freePhysicalMemory / (1024 * 1024) + " MB");
        System.out.println("已用物理内存: " + (totalPhysicalMemory - freePhysicalMemory) / (1024 * 1024) + " MB");
        System.out.println("已用物理内存: " + getSystemMemoryUsage() + " MB");
        double cpuUsage = getSystemCpuUsage();
        int count = 0;
        while (true)
        {
            System.out.println("CPU Usage: " + cpuUsage + "%");
            cpuUsage = getSystemCpuUsage();
            //count++;
            sleep(5000);
            if(count > 5000000)
            {
                break;
            }
        }
        System.out.println("CPU Usage: " + cpuUsage + "%");

    }
    public static double getSystemMemoryUsage() {
        // 获取操作系统MXBean
        OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        // 获取总物理内存和空闲物理内存
        long totalPhysicalMemory = osBean.getTotalPhysicalMemorySize();
        long freePhysicalMemory = osBean.getFreePhysicalMemorySize();
        // 返回内存使用情况

        // System.out.println("总物理内存: " + totalPhysicalMemory / (1024 * 1024) + " MB");
        // System.out.println("空闲物理内存: " + freePhysicalMemory / (1024 * 1024) + " MB");
        // System.out.println("已用物理内存: " + (totalPhysicalMemory - freePhysicalMemory) / (1024 * 1024) + " MB");
        return (totalPhysicalMemory - freePhysicalMemory) / (1024 * 1024);
    }
    public static double getSystemTotalMemory() {
        // 获取操作系统MXBean
        OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        // 获取总物理内存和空闲物理内存
        long totalPhysicalMemory = osBean.getTotalPhysicalMemorySize();
        long freePhysicalMemory = osBean.getFreePhysicalMemorySize();
        // 返回内存使用情况

        // System.out.println("总物理内存: " + totalPhysicalMemory / (1024 * 1024) + " MB");
        // System.out.println("空闲物理内存: " + freePhysicalMemory / (1024 * 1024) + " MB");
        // System.out.println("已用物理内存: " + (totalPhysicalMemory - freePhysicalMemory) / (1024 * 1024) + " MB");
        return totalPhysicalMemory / (1024 * 1024);
    }
    public static double getSystemCpuUsage() {
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
        double cpuUsage = 0.0;

        if (operatingSystemMXBean instanceof com.sun.management.OperatingSystemMXBean) {
            // For Windows
            com.sun.management.OperatingSystemMXBean sunOsMxBean = (com.sun.management.OperatingSystemMXBean) operatingSystemMXBean;
            cpuUsage = sunOsMxBean.getSystemCpuLoad() * 100.0;
        } else {
            // For Linux
            // Handle Linux case if needed
        }

        return cpuUsage;
    }
}
